package com.okilo.online.app.tools.log

import android.text.TextUtils
import android.util.Log
import com.okilo.online.app.BuildConfig

/**
 * Logger
 * @Author wwdeng
 * @CreateTime: 2024/11/8 11:14
 * @Annotation：日志帮助类
 */
object OkiloLog {
    var isDebug: Boolean = true

    var TAG: String = BuildConfig.appName

    private val SEGMENT_MAX_SIZE = 3 * 1024
    private const val STACK_TRACE_ELEMENT_INDEX = 4
    private const val V = 1
    private const val D = 2
    private const val I = 3
    private const val W = 4
    private const val E = 5

    fun debug(isEnable: Boolean) {
        isDebug = isEnable
    }

    /**
     * 对应Log.e(String tag, String msg)进行打印，日志等级：错误
     * @param object 日志内容，需要被打印输出的内容
     * ERROR 输出为红⾊
     */
    @JvmStatic
    fun e(`object`: Any?) {
        showLogAction(E, `object`)
    }

    /**
     * 对应Log.v(String tag, String msg)进行打印，日志等级：错误
     * @param object 日志内容，需要被打印输出的内容
     * VERBOSE  输出颜⾊为⿊⾊
     */
    fun v(`object`: Any?) {
        showLogAction(V, `object`)
    }

    /**
     * 对应Log.d(String tag, String msg)进行打印，日志等级：错误
     * @param object 日志内容，需要被打印输出的内容
     * DEBUG 输出颜⾊是蓝⾊
     */
    fun d(`object`: Any?) {
        showLogAction(D, `object`)
    }

    /**
     * 对应Log.i(String tag, String msg)进行打印，日志等级：错误
     * @param object 日志内容，需要被打印输出的内容
     * INFO 输出为绿⾊
     */
    @JvmStatic
    fun i(`object`: Any?) {
        showLogAction(I, `object`)
    }

    /**
     * 对应Log.w(String tag, String msg)进行打印，日志等级：错误
     * @param object 日志内容，需要被打印输出的内容
     * WARN 输出为橙⾊
     */
    fun w(`object`: Any?) {
        showLogAction(W, `object`)
    }

    private fun showLogAction(type: Int, `object`: Any?) {
        if (!isDebug) {
            return
        }
        var illegalTag = false
        var illegalObject = false
        if (TextUtils.isEmpty(TAG)) {
            illegalTag = true
        }
        if (`object` == null || `object`.toString().length == 0) {
            illegalObject = true
        }
        if (illegalTag || illegalObject) {
            return
        }
        var message = `object`.toString()
        val length = message.length
        if (length <= SEGMENT_MAX_SIZE) {
            formatLog(type, TAG, message)
        } else {
            while (message.length > SEGMENT_MAX_SIZE) {
                val logContent = message.substring(0, SEGMENT_MAX_SIZE)
                message = message.substring(SEGMENT_MAX_SIZE)
                formatLog(type, TAG, logContent)
            }
            formatLog(type, TAG, message)
        }
    }

    /**
     * 格式化并执行打印
     * @param type 日志等级，包含 5 种：V、D、I、W、E，且只能是这4个
     * @param tag 标签
     * @param object 日志内容
     */
    private fun formatLog(type: Int, tag: String?, `object`: Any) {
        val stackTraceElements = Thread.currentThread().getStackTrace()
        val filename = stackTraceElements[STACK_TRACE_ELEMENT_INDEX]!!.getFileName()
        val classStr = stackTraceElements[STACK_TRACE_ELEMENT_INDEX]!!.getClassName()
        val methodStr = stackTraceElements[STACK_TRACE_ELEMENT_INDEX]!!.getMethodName()
        val lineNumber = stackTraceElements[STACK_TRACE_ELEMENT_INDEX]!!.getLineNumber()

        val stringBuilder = StringBuilder()
        stringBuilder.append("[ (").append(filename).append(":").append(lineNumber).append(")#")
            .append(methodStr).append(" ]")

        val messageContent = `object`.toString()
        stringBuilder.append("==> " + messageContent)

        when (type) {
            V -> Log.v(tag, stringBuilder.toString())
            D -> Log.d(tag, stringBuilder.toString())
            I -> Log.i(tag, stringBuilder.toString())
            W -> Log.w(tag, stringBuilder.toString())
            E -> Log.e(tag, stringBuilder.toString())
            else -> {}
        }
    }
}
